|
Date : 8 ao�t 1991, 8 septembre 1991 ( fin ) Protection : MOT DE PASSE Programme : SUPER.C Outils : SOFT-ICE V2.50, QUAID, MASM, LINK, EXE2BIN, ST.COM, SOURCER, BIBLE PC, et j'en oublie... Fichier : STO.COM ( personnel ) Temps pass� : 1 SEMAINE ( mise au point ) Soci�t� : KONAMI Divers : Compact� par un compacteur maison Origine : INDONESIE Num�ro : 139 8 Ao�t 1991; On trouve de suite le saut � modifier en 1465:008C mais la cha�ne qui l'entoure n'appara�t pas dans le fichier, et ce dernier n'est ni compact� par LZEXE ni EXEPACK ni PKLITE. 1465:0089 3B46E2 1465:008C 7422 JZ ... ; A REMPLACER PAR EB ( JMP ) 1465:008E 8D Donc la solution du d�tournement d'interruption s'impose automatiquement mais malheureusement d�s que l'INT 21 ne pointe plus sur son vecteur d'origine le SOFT le d�tecte et refuse de continuer en disant qu'il ne dispose plus assez de m�moire. Ce qui est faux; j'ai v�rifi� ! En fait n'importe quelle interruption d�tourn�e fait afficher le m�me message. D'autres essais mettent en �vidence que SUPER_C ne supporte pas trop les programmes r�sidents; il ne r�agit pas pour NC, MOUSE.COM, et SOFT-ICE ( encore heureux ! ). Par contre il "jette" mes FRED.COM ainsi que PERISCOPE et QUAID. Peut-�tre que je ne lib�re pas assez de m�moire avec mes FREDs, mais ils ne prennent qu'en moyenne 200 � 300 octets lorsqu'ils sont r�sidents, alors quoi...? Une ruse du programmeur ou un d�faut de mes FRED.COM ? A voir... Premi�re semaine de Septembre 1991; Je d�cide d'examiner la "soluce" de STUNTS qui consiste �galement � d�tourner l'INT 21 ( tiens on m'a copi� ! ) par contre l'auteur qui n'est pas avare d'�loges et qui laisse volontairement tra�ner son adresse dans presque tous les fichiers ( voir les infos.com de STUNTS ) proc�de avec une approche diff�rente. Son programme commence � ne r�server que la m�moire utile n�cessaire, puis il d�tourne l'INT 21 sous-fonction 1A ( set DTA ) sur un vecteur personnel qui ira modifier le test de la protection du jeu. Apr�s cela il charge le programme du jeu normalement par la fonction EXEC sous- fonction 00 de l'INT 21. D�s que l'on quitte le jeu le contr�le est rendu � son programme qui replace le vecteur de l'INT 21 sur sa valeur d'origine et quitte le jeu par la fonction 4C de l'INT 21. C'est plus �l�gant car cela �vite de faire un fichier BATCH qui appelle FRED.COM puis le jeu, et rappelle FRED.COM pour qu'il se d�sinstalle. Par contre si j'avais su ce qui m'attendait en me lan�ant dans ce mini- projet ( qui n'a de mini que le nom ) je n'aurais jamais commenc� d'autant plus qu'actuellement tout ne fonctionne pas encore comme il faudrait; SUPER_C revient au DOS avec un message d'erreur du style: ERROR XXXX, NULL ASSIGNEMENT POINTER. Mais enfin la protection est "stripp�e" et le jeu ne se plante pas ! En bref; trois jours de "brain storming", d'essais en tout genre, la bible PC feuillet�e du d�but � la fin ( pour m'apercevoir qu'il me manquait malgr� tout des infos ), de plantages chroniques, en passant par la correction du lanceur de STUNTS avec en prime la carte sonore qui faisait �galement des siennes lorsqu'elle est d�clar�e en SOUND BLASTER et qui fonctionne correctement lorsqu'on l'appelle ADLIB. ( c'est bien une SOUND BLASTER que j'ai ramen�e ? ). Un point positif toutefois; j'ai appris une foule de choses sur le fonctionnement des COM, EXE, OVL et TSR ainsi que sur la fonction 4B qui n'est pas si simple � mettre en oeuvre... Ci-dessous le lanceur du jeu STUNT corrig�.... Le segment SP �tait �cras� par le segment DS, une instruction MOV BX,[BP+0A] �tait inutile puisque BX n'�tait pas utilis� dans la routine de l'INT 21 d�tourn�e. Ce qui m'a permis d'enlever �galement un PUSH BX et son POP. A ce moment malheureusement la protection ne fonctionnait plus. En fait SP �tait charg� dans BP et avec un PUSH en moins il a donc fallu corriger l'instruction suivante MOV AX,[BP-0C] en MOV AX,[BP-0A] ! ouf. Un autre probl�me du au fait que SOURCER dessassemble en pla�ant des r�f�rences d'adresses dans les instructions au lieu d'�tiquettes m'a plant� mon programme lorsque j'avais rajout� une DATA DW 0. En faisant cela la r�f�rence du d�but de mon pointeur INT21 se trouvait d�caler de +2. data_11e equ 459Bh seg_a segment byte public assume cs:seg_a, ds:seg_a org 100h sto proc far start: jmp loc_1 db 90h nom_prg db 'STUNTS.COM',0,0,0 ; 12 car max + nul paramet db 0, 0 ; Pour les d�tails voir la ENVIR dw 0 ; bible PC ou moi-m�me... data_3 dw 0 FCB_1 dw 0 data_5 dw 0 FCB_2 dw 0 data_7 dw 0 sauve_SP dw 0 ; Premi�re correction. sauve_SS dw 0 data_9 dw 0, 0 loc_1: mov sauve_SP,sp ; On sauve SP et mov sauve_SS,ss ; SS car la fonction EXEC les d�truit. mov ah,4Ah mov bx,2Fh int 21h ; lib�re la m�moire, bx=nbr paragraphes mov ax,80h mov ENVIR,ax ; Ligne de commande. mov data_3,ds mov ax,5Ch ; Premier FCB. mov FCB_1,ax mov data_5,ds mov ax,6Ch ; Second FCB. mov FCB_2,ax mov data_7,ds mov ah,35h mov al,21h int 21h ; On r�cup�re le vecteur de l'INT 21 mov cs:data_9,bx mov word ptr cs:data_9+2,es mov ah,25h mov al,21h lea dx,cs:[int21] ; Load effective addr int 21h ; l'INT 21 pointe sur un autre vecteur. lea dx,cs:[nom_prg] ; Load effective addr push ds pop es lea bx,cs:[paramet] ; Load effective addr mov al,0 mov ah,4Bh int 21h ; run progm @ds:dx, parm @es:bx mov sp,sauve_SP mov ss,sauve_SS mov ah,25h mov al,21h mov dx,cs:data_9 mov ds,word ptr cs:data_9+2 int 21h ; on replace le vecteur d'origine. mov ah,4Ch int 21h ; on quitte. sto endp ; int 21 d�tourn�e... int_21h_entry proc far int21: push ax push ds ; push bx ; supprim�. push bp pushf ; Push flags cmp ah,1Ah jne loc_2 ; Jump if not equal cmp dx,3FE4h jne loc_2 ; Jump if not equal mov bp,sp ; mov bx,[bp+0ah] ; deuxi�me correction. mov ax,[bp+0ah] ; Modifi� ( d'origine + 0Ch ) sub ax,1DF1h mov ds,ax mov ax,ds:data_11e cmp ax,775h jne loc_2 ; Jump if not equal mov word ptr ds:data_11e,9090h loc_2: popf ; Pop flags pop bp ; pop bx ; supprim�. pop ds pop ax jmp dword ptr cs:data_9 int_21h_entry endp seg_a ends end start Cette routine adapt�e � n'importe quel programme COM fonctionne parfaitement ainsi que pour les programmes EXE de moins de 64k ! �a commence. Les programmes sup�rieurs � 64k se plante d�s que l'on veut les quitter. Un programme compact� par LZ91 qui pr�sente une taille inf�rieure � 64k se crache �galement mais c'est normal puisqu'une foi d�compact� en m�moire il d�passe 64k. La premi�re correction effectu�e ( sauvegarde correcte de SS:SP ) les programmes EXE reviennent au DOS normalement quelque soit leur taille. J'assemble une version pour SUPER_C sans d�tournement d'INT pour voir. Le probl�me consiste � v�rifier si les param�tres de la ligne de commande sont bien transmis de mon programme au programme de SUPER_C et si celui-ci ne fait pas une allergie. SUPER_C est lanc� comme suit: LOAD /U EGA 1, je lance donc mon programme appel� STO avec les m�mes param�tres. Et cela fonctionne ! Je v�rifie rapidement avec SOFT-ICE et effectivement je trouve bien au d�but de l'adresse 0080h de mon STO la cha�ne LOAD /U EGA 1. Le dernier essai avant de crier victoire est de d�tourner l'INT 21 et de relancer. L'INT 21 est simplement d�tourn�e sans traitement. Le jeu se charge toujours correctement. Cette fois-ci il ne suffit plus que de patcher l'endroit du test de la protection. C'est vite dit et je n'arrive pas � trouver mon segment IP qui comporte mon saut 7422. J'essaie une autre interruption que la 1A sans meilleur r�sultat. Avec SOFT-ICE je vois que la routine est �crite en m�moire d�s le tout d�but du chargement du programme, mais impossible de mettre la main dessus par la suite que ce soit par l'interm�diaire de BP, ES, DX, ou plus simplement SS. Je fais une recherche de 65536 octets sur chacun de ces segments sans r�sultat. Je PUSHe et POPe SP de plus et moins 50 en vain. Pourtant lors de la demande du code la routine est bien l� quelque POP plus hauts ! Le probl�me est que l'INTERRUPTION 21 n'est plus appel�e dans la zone de demande du mot de passe. Une solution radicale existe pourtant c'est de d�tourner l'INT 09 qui elle se d�clenche d�s que l'on appuie sur une touche. ( il n'y a rien de plus pr�s ! ) mais c'est une IT hard. Dans le programme les caract�res sont demand�s par l'INT 16 sous- fonction 01. Je la d�tourne pour voir et c'est tout vu; cela fonctionne. Ci-dessous le programme en assembleur il ne reste plus qu'un probl�me � r�soudre c'est d'�viter le message NUL POINTER ASSIGNEMENT. ; PATCH POUR LE PROGRAMME SUPER_C ; DETOURNEMENT DE L'INT 16 SOUS-FONCTION 01 adr_ip equ 8ch seg_a segment byte public assume cs:seg_a, ds:seg_a, es:seg_a, ss:seg_a org 100h sto proc far start: jmp init ; r�duire la m�moire et d�placer la db 90h ; pile plus pr�s. nom_prg db 'load.exe',0,0,0,0,0 ; 12 car max + nul paramet dw 0 ; M�me bloc d'environnement. ENVIR dw 0 ; Les param�tres de la ligne de data_3 dw 0 ; commande sont recopi�s ici puis FCB_1 dw 0 ; transmis au programme fils. ( 80h ) data_5 dw 0 ; "LOAD /U EGA 1" FCB_2 dw 0 data_7 dw 0 sauve_SP dw 0 sauve_SS dw 0 data_9 dw 0, 0 drap equ 0 ;------------------------------ PROGRAMME PERE ------------------------------ loc_1: mov sauve_SP,sp mov sauve_SS,ss mov ax,80h mov ENVIR,ax ; Ligne de commande... mov data_3,ds mov ax,5Ch ; Premier FCB ( inutilis� ) mov FCB_1,ax mov data_5,ds mov ax,6Ch ; Second FCB ( inutilis� ) mov FCB_2,ax mov data_7,ds mov ah,35h mov al,16h int 21h ; DOS Services ah=function 35h ; get intrpt vector al in es:bx mov cs:data_9,bx mov word ptr cs:data_9+2,es mov ah,25h mov al,16h lea dx,cs:[int16] ; Load effective addr int 21h ; DOS Services ah=function 25h ; set intrpt vector al to ds:dx lea dx,cs:[nom_prg] ; Load effective addr push ds pop es lea bx,cs:[paramet] ; Load effective addr mov al,0 mov ah,4Bh int 21h ; Appel du programme fils. ; run progm @ds:dx, parm @es:bx mov sp,sauve_SP mov ss,sauve_SS mov ah,25h mov al,16h mov dx,cs:data_9 mov ds,word ptr cs:data_9+2 int 21h ; set intrpt vector al to ds:dx mov ah,4dh int 21h mov ah,4Ch int 21h ; terminate with al=return code sto endp ;---------------------------- int 16 d�tourn�e ----------------------------- int_16h_entry proc far int16: push ax push ds push bp push cx pushf ; Push flags cmp byte ptr ds:[drap],1 ; Je regarde si c'est fait. jz loc_2 cmp ah,1 ; Sous- fonction 01 jne loc_2 ; Jump if not equal mov ax,sp mov bp,ds mov cx,20 ; On pope 20 fois pour trouver incr: pop ds ; le bon segment. dec cx jz s cmp word ptr ds:[adr_ip],2274h ; Si ok on patche. jnz incr ; Sinon on incr�mente. mov byte ptr ds:[adr_ip],0ebh mov ds,bp mov byte ptr ds:[drap],1 ; On y revient plus. s: mov sp,ax loc_2: popf pop cx pop bp pop ds pop ax jmp dword ptr cs:data_9 int_16h_entry endp ;------------ REDUCTION DE LA PLACE OCCUPEE PAR LE PROGRAMME COM ------------ init: mov ah,4ah mov bx,offset fin ; Fin du programme en BX. mov cl,4 ; Divis� par 4 pour avoir des paragraphes. shr bx,cl inc bx ; On en rajoute un par s�curit�. int 21h ; Execution de la fonction 4Ah. mov sp,offset fin ; on d�place la pile en "fin" car elle est jmp loc_1 ; plac�e en FFFE dans un programme COM. fin_init label near ;----------------------- PLACE RESERVEE POUR LA PILE ------------------------ dw (256-((fin_init-init) shr 1)) dup (?) fin equ this byte ; ici le sommet de la pile, SP seg_a ends end start |